package cn.yitun.chat.yitunchatnettysdk.netty.web;

import cn.yitun.chat.yitunchatbasesdk.server.im.dispatcher.handler.SessionHandler;
import cn.yitun.chat.yitunchatbasesdk.server.im.dispatcher.handler.SessionMessageHandler;
import cn.yitun.chat.yitungeneral.annotation.socket.Server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author yitun
 */
public final class WebSocketServer implements Server {

	protected final Logger logger = LoggerFactory.getLogger(this.getClass());
	private int port = 9000;
	private ServerBootstrap server = new ServerBootstrap();
	private boolean start = false;
	private String websocketPath;

	private SessionMessageHandler messageHandler;
	private SessionHandler sessionHandler;

	public WebSocketServer(String websocketPath, SessionMessageHandler messageHandler, SessionHandler sessionHandler) {
		this.websocketPath = websocketPath;
		this.messageHandler = messageHandler;
		this.sessionHandler = sessionHandler;
	}

	public boolean start() {
		if (start) {
			return start;
		}
		EventLoopGroup bossGroup = new NioEventLoopGroup(1);
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			start = true;
			server.group(bossGroup, workerGroup);
			server.channel(NioServerSocketChannel.class);
			server.handler(new LoggingHandler(LogLevel.DEBUG));
			server.childHandler(new WebSocketServerInitializer(websocketPath, messageHandler, sessionHandler));
			// server.bind(port);
			Channel ch = server.bind(port).sync().channel();
			ch.closeFuture().sync();
		} catch (InterruptedException ex) {
			start = false;
			logger.error("WebSocketServer启动失败", ex);
		} finally {
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}
		return start;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}
}
